package com.fernandomartines.dbcheck.graph;

import com.fernandomartines.dbcheck.graph.element.ModelGraphAssociation;
import com.fernandomartines.dbcheck.graph.element.ModelGraphAttribute;
import com.fernandomartines.dbcheck.graph.element.ModelGraphConstraint;
import com.fernandomartines.dbcheck.graph.element.ModelGraphEntity;
import com.fernandomartines.dbcheck.graph.element.ModelGraphOperation;
import com.fernandomartines.dbcheck.graph.element.ModelGraphParameter;
import com.fernandomartines.dbcheck.graph.element.ModelGraphQualifier;

public class ModelGraphPrinter {

    public static void print(ModelGraph graph) {

        System.out.println("\n#GRAPH: ------------------------------------------------------------");

        if (graph == null) {
            System.out.println("\nGraph is empty (NULL)");
            return;
        }

        StringBuilder sb = new StringBuilder();
        sb.append("\nENTITIES (" + graph.getEntities().size() +")");
        for (ModelGraphEntity entity: graph.getEntities()) {
            sb.append("\n\n\tENTITY: " + entity.getName());
            sb.append("\n\tAttributes (" + entity.getAttributes().size() + ")");
            for (ModelGraphAttribute attribute: entity.getAttributes()) {
                sb.append("\n\t\t");
                sb.append(attribute.getName());
                sb.append(" : ");
                sb.append(attribute.getType());
                for (ModelGraphQualifier qualifier: attribute.getQualifiers()) {
                    sb.append(" ");
                    sb.append(ModelGraphParser.QualifierTokens.charAt(0));
                    sb.append(qualifier.getName());
                    sb.append(ModelGraphParser.QualifierTokens.charAt(1));
                }
                for (ModelGraphConstraint constraint: attribute.getConstraints()) {
                    sb.append(" ");
                    sb.append(ModelGraphParser.ConstraintTokens.charAt(0));
                    sb.append(constraint.getName());
                    sb.append(ModelGraphParser.ConstraintTokens.charAt(1));
                }
            }
            sb.append("\n\tOperations (" + entity.getOperations().size() + ")");
            for (ModelGraphOperation operation: entity.getOperations()) {
                int flag = 0;
                sb.append("\n\t\t");
                sb.append(operation.getName());
                sb.append(" (");
                for (ModelGraphParameter parameter: operation.getParameters()) {
                    if (flag++ > 0) sb.append(", ");
                    sb.append(parameter.getName());
                    sb.append(": ");
                    sb.append(parameter.getType());
                }
                sb.append(")");
                for (ModelGraphQualifier qualifier: operation.getQualifiers()) {
                    sb.append(" ");
                    sb.append(ModelGraphParser.QualifierTokens.charAt(0));
                    sb.append(qualifier.getName());
                    sb.append(ModelGraphParser.QualifierTokens.charAt(1));
                }
                for (ModelGraphConstraint constraint: operation.getConstraints()) {
                    sb.append(" ");
                    sb.append(ModelGraphParser.ConstraintTokens.charAt(0));
                    sb.append(constraint.getName());
                    if (constraint.getValue() != null)
                        sb.append(": " + constraint.getValue());
                    sb.append(ModelGraphParser.ConstraintTokens.charAt(1));
                }
            }
        }
        sb.append("\nASSOCIATIONS (" + graph.getAssociations().size() +")");
        for (ModelGraphAssociation association: graph.getAssociations()) {
            sb.append(association.getAssociationStart().getEntity().getName());
            sb.append("(" + association.getAssociationStart().getMin() + ".." + association.getAssociationStart().getMax() + ")");
            sb.append(" <-----> ");
            sb.append("(" + association.getAssociationEnd().getMin() + ".." + association.getAssociationEnd().getMax() + ")");
            sb.append(association.getAssociationEnd().getEntity().getName());
        }
        System.out.println(sb.toString());
    }

}
